package com.example.gateway.filter;

import cn.hutool.core.util.StrUtil;
import com.copyctrl.campus.common.constant.HttpConstant;
import com.copyctrl.campus.common.utils.StringUtils;
import com.example.gateway.config.IgnoreUrlsConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.annotation.Order;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

@Order(1)
@Component
/**
 * 检验redis中是否存在用户，不存在则拦截，是未登录状态，存在把用户信息存入UserHolder中
 * 需要看看经过网关的请求是否为同一个线程，存放在ThreadLocal中通过网关的filter之后是否能从UserHolder中取到数据
 * TODO UserHolder可能不行，别人的解决方案是从redis中取出数据后把json解析成对象放入request请求头中  设计初级阶段 保留问题
 */
public class AuthorizeFilter implements GlobalFilter {

    @Autowired
    private IgnoreUrlsConfig ignoreUrlsConfig;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 1.获取请求参数
        ServerHttpRequest request = exchange.getRequest();
        String url = request.getURI().getPath();
        // 跳过不需要验证的路径
        if (StringUtils.matches(url,ignoreUrlsConfig.getUrls()))
        {
            return chain.filter(exchange);
        }
        MultiValueMap<String, String> params = request.getHeaders();
        // 2.获取参数中的 authorization 参数
        String auth = params.getFirst(HttpConstant.USER);
        if (!StrUtil.isEmpty(auth)) {
            // 4.不为空，放行
            return chain.filter(exchange);
        }
        // 5.为空，拦截
        // 5.1.设置状态码
        exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
        // 5.2.拦截请求
        return exchange.getResponse().setComplete();
    }
}
